package com.thornbird.vehiclerecycling.util;

import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.*;
import com.thornbird.vehiclerecycling.model.record.OrderRecord;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PdfUtil {

    public static final String XINHUA_SONGTI = "xinhua_songti.ttf";

    public static final String XINHUA_KAITI = "xinhua_kaiti.ttf";

    public static final String FANGZHENG_FANGSONG_GBK = "fangzheng_fangsong_gbk.ttf";

    public static final String RUIZIYUNZIKU_XIAOBIAO_SONGTI = "ruiziyunziku_xiaobiao_songti.ttf";

    public static final String[] NUMBERS = new String[] {"一", "二", "三", "四", "五", "六"};

    public static final String[] LABELS = new String[] {
            "车主留存",
            "交当地公安交通管理部门备查",
            "回收企业留存",
            "交当地商务主管部门备查",
            "用于申领补贴资金",
            "交当地交通运输管理部门备查"
    };

    public static final Map<String, String> FONT_MAP = new HashMap<String, String>() {{
        put(XINHUA_SONGTI, "XinHuaSongTi");
        put(XINHUA_KAITI, "XinHuaKaiTi");
        put(FANGZHENG_FANGSONG_GBK, "FangZhengFangSongGBK");
        put(RUIZIYUNZIKU_XIAOBIAO_SONGTI, "RuiZiYunZiKuXiaoBiaoSongTi");
    }};

    private static String fontPath;

    public static void setFontPath(String path) {
        fontPath = path;
        for (Map.Entry<String, String> entry : FONT_MAP.entrySet()) {
            PdfFontFactory.register(fontPath + entry.getKey(), entry.getValue());
        }
    }

    public static PdfWriter createPdfWriter(HttpServletResponse response, String filename) throws IOException {
        String finalFilename = new String(filename.getBytes("GB2312"), "ISO8859-1");
        response.setHeader("Content-Type", "application/pdf");
        response.addHeader("Content-Disposition", "attachment;filename=" + finalFilename);
        PdfWriter pdfWriter = new PdfWriter(response.getOutputStream());
        return pdfWriter;
    }

    public static Document createDocument(PdfWriter pdfWriter) {
        return createDocument(pdfWriter, false, null);
    }

    public static Document createDocument(PdfWriter pdfWriter, boolean landscape) {
        return createDocument(pdfWriter, landscape, null);
    }

    public static Document createDocument(PdfWriter pdfWriter, boolean landscape, List<String> backgroundImages) {
        PdfDocument pdfDocument = new PdfDocument(pdfWriter);
        pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new BackgroundEventHandler(null, backgroundImages));
        return new Document(pdfDocument, landscape ? PageSize.A4.rotate() : PageSize.A4);
    }

    public static void saveDocument(Document document, PdfWriter pdfWriter) throws IOException {
        pdfWriter.getOutputStream().flush();
        document.close();
        document.getPdfDocument().close();
    }

    public static void createRecyclingCertificate(Document document, OrderRecord orderRecord, String authoritySignature,
                                                  int index, boolean addNextPage)
            throws IOException {
        document.setMargins(43, 43, 40, 47);
        if (addNextPage) {
            document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        }
        document.add(new Paragraph("报废机动车回收证明").setFont(createFont(XINHUA_SONGTI)).setFontSize(19)
                .setTextAlignment(TextAlignment.CENTER).setMultipliedLeading(0.55f));
        document.add(new Paragraph("（吉林省）").setFont(createFont(XINHUA_KAITI)).setFontSize(13)
                .setTextAlignment(TextAlignment.CENTER).setMultipliedLeading(0.20f));

        int pageCount = document.getPdfDocument().getNumberOfPages();
        Rectangle rectangle = document.getPdfDocument().getPage(pageCount).getPageSize();
        float tableWidth = rectangle.getWidth() - 90;

        UnitValue[] unitValues = new UnitValue[] {
                UnitValue.createPercentValue(9.5f),
                UnitValue.createPercentValue(51.8f),
                UnitValue.createPercentValue(9.5f),
                UnitValue.createPercentValue(29.2f)
        };
        Table table = new Table(unitValues);
        table.setWidth(tableWidth);
        table.addCell(createTableCellNoBorder("回收企业名称：", 1, 1, XINHUA_SONGTI, 23, 0));
        table.addCell(createTableCellNoBorder(orderRecord.getCompanyName(), 1, 1, XINHUA_SONGTI, 23, 0));
        table.addCell(createTableCellNoBorder("回收证明编号：", 1, 1, XINHUA_SONGTI, 23, 0));
        table.addCell(createTableCellNoBorder(orderRecord.getCertificateNumber(), 1, 1,
                XINHUA_SONGTI, 26, 0));
        document.add(table);

        unitValues = new UnitValue[] {
                UnitValue.createPercentValue(9.17f),
                UnitValue.createPercentValue(15.65f),
                UnitValue.createPercentValue(13.15f),
                UnitValue.createPercentValue(9.22f),
                UnitValue.createPercentValue(11.51f),
                UnitValue.createPercentValue(9.12f),
                UnitValue.createPercentValue(9.17f),
                UnitValue.createPercentValue(20.18f),
                UnitValue.createPercentValue(2.83f)
        };
        table = new Table(unitValues);
        table.setWidth(tableWidth);

        table.addCell(createTableCell("车主名称", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getOwnerName(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("车主身份证号/ 代码证号", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getIdNumber(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("车主联系电话", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getPhoneNumber(), 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCellNoBorder("第" + NUMBERS[index - 1] + "联", 2, 1, XINHUA_SONGTI, 10.2f, 73.2f, 0, 20)
                .setPaddingLeft(7));

        table.addCell(createTableCell("车主地址", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getAddress(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("交车日期", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(DateUtil.formatDate(orderRecord.getDeliveryDate(), DateUtil.DATE_FORMAT), 1, 2,
                XINHUA_SONGTI, 0));
        table.addCell(createTableCell("注册登记日期", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(DateUtil.formatDate(orderRecord.getRegistrationDate(), DateUtil.DATE_FORMAT), 1, 1,
                XINHUA_SONGTI, 0));

        table.addCell(createTableCell("车辆牌照号码", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getVehicleNumber(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("车辆类型", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getVehicleType(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("车辆使用性质", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getVehicleNature(), 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCellNoBorder(LABELS[index - 1] + "联", 4, 1, XINHUA_SONGTI, 10.2f, 209.8f, 0, 12)
                .setPaddingLeft(7));

        table.addCell(createTableCell("车辆品牌型号", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(getTexts(orderRecord.getVehicleBrand(), orderRecord.getVehicleModel()), 1, 2,
                XINHUA_SONGTI, 0));
        table.addCell(createTableCell("车辆识别代号", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getVin(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("整备质量(kg)", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getWeight() == null ? null : orderRecord.getWeight().toString(), 1, 1,
                XINHUA_SONGTI, 0));

        table.addCell(createTableCell("动力类别", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getPowerType(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("发动机号码", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getEngineNumber(), 1, 2, XINHUA_SONGTI, 0));
        table.addCell(createTableCell("动力电池编码", 1, 1, XINHUA_SONGTI, 0));
        table.addCell(createTableCell(orderRecord.getBatteryNumber(), 1, 1, XINHUA_SONGTI, 0));

        Image qrCodeImage = null;
        if (orderRecord.getCheckCode() != null) {
            byte[] qrCodeData = null;
            try {
                qrCodeData = QRCodeUtil.generateQRCode(orderRecord.getCheckUrl());
            } catch (Exception e) {
                throw new IOException("QRCode error: " + e.getMessage());
            }
            qrCodeImage = new Image(ImageDataFactory.create(qrCodeData));
        }
        table.addCell(addImageToCell(createTableCell("（二维码）", 2, 2, XINHUA_SONGTI, 129, 0)
                .setVerticalAlignment(VerticalAlignment.BOTTOM).setPaddingBottom(10), qrCodeImage, 89, 153, 100));

        table.addCell(addImageToCell(createTableCell("商务主管部门（章）", 2, 3, XINHUA_SONGTI, 129, 0)
                .setTextAlignment(TextAlignment.LEFT).setVerticalAlignment(VerticalAlignment.TOP)
                .setPaddingLeft(5).setPaddingTop(21), authoritySignature, 310, 140, 130));

        String operator = getTexts("经办人：", orderRecord.getOperator());
        String processingDate = DateUtil.formatDate(orderRecord.getProcessingDate(), DateUtil.CHINESE_DATE_FORMAT);
        table.addCell(createTableCell("回收企业（章）", 1, 3, XINHUA_SONGTI, 100, 0)
                .setTextAlignment(TextAlignment.LEFT).setVerticalAlignment(VerticalAlignment.TOP)
                .setPaddingLeft(5).setPaddingTop(21).setBorderBottom(Border.NO_BORDER));
        table.addCell(createTableCell(operator, 1, 2, XINHUA_SONGTI, 29, 0)
                .setTextAlignment(TextAlignment.LEFT).setVerticalAlignment(VerticalAlignment.BOTTOM)
                .setPaddingLeft(8).setPaddingBottom(14).setBorderTop(Border.NO_BORDER).setBorderRight(Border.NO_BORDER));
        table.addCell(createTableCell(processingDate, 1, 1, XINHUA_SONGTI, 29, 0)
                .setTextAlignment(TextAlignment.RIGHT).setVerticalAlignment(VerticalAlignment.BOTTOM)
                .setPaddingRight(8).setPaddingBottom(14).setBorderTop(Border.NO_BORDER).setBorderLeft(Border.NO_BORDER));

        table.addCell(createTableCellNoBorder("共六联", 2, 1, XINHUA_SONGTI, 10.2f, 70, 0, 20)
                .setPaddingLeft(7));
        table.addCell(createTableCell(getTexts("说明：", orderRecord.getRemark()), 1, 8, XINHUA_SONGTI, 41)
                .setTextAlignment(TextAlignment.LEFT));
        document.add(table);

        unitValues = new UnitValue[] {
                UnitValue.createPercentValue(3.25f),
                UnitValue.createPercentValue(47f),
                UnitValue.createPercentValue(47f),
                UnitValue.createPercentValue(2.75f)
        };
        table = new Table(unitValues);
        table.setWidth(tableWidth);
        table.addCell(createTableCellNoBorder("No.", 1, 1, FANGZHENG_FANGSONG_GBK, 26, 0)
                .setVerticalAlignment(VerticalAlignment.BOTTOM)
                .setFontSize(11).setFontColor(new DeviceRgb(220, 80, 50)));
        table.addCell(createTableCellNoBorder(orderRecord.getSerialNumber(), 1, 1, FANGZHENG_FANGSONG_GBK, 26, 0)
                .setVerticalAlignment(VerticalAlignment.BOTTOM)
                .setFontSize(16).setFontColor(new DeviceRgb(220, 80, 50)));
        table.addCell(createTableCellNoBorder("吉林省商务厅监印", 1, 1, XINHUA_SONGTI, 26, 0)
                .setFontSize(9.5f).setTextAlignment(TextAlignment.RIGHT).setPaddingRight(8));
        document.add(table);
    }

    public static void createCancellationCertificate(Document document, OrderRecord orderRecord) throws IOException {
        document.setMargins(35, 30, 35, 30);
        document.add(new Paragraph("机动车注销证明书").setFont(createFont(RUIZIYUNZIKU_XIAOBIAO_SONGTI)).setFontSize(21)
                .setTextAlignment(TextAlignment.CENTER).setMarginBottom(30));

        int pageCount = document.getPdfDocument().getNumberOfPages();
        Rectangle rectangle = document.getPdfDocument().getPage(pageCount).getPageSize();
        float tableWidth = rectangle.getWidth() - 60;
        UnitValue[] unitValues = new UnitValue[] {
                UnitValue.createPercentValue(30),
                UnitValue.createPercentValue(70)
        };
        Table table = new Table(unitValues);
        table.setWidth(tableWidth);
        table.setBorder(new SolidBorder(new DeviceRgb(0, 0, 0), 1));

        Cell cell = createTableCellNoBorder(null, 1, 2, XINHUA_SONGTI, 14, 0, 10);
        Paragraph paragraph = new Paragraph("在我所登记的下列机动车，因 报废 已办理注销登记。").setFirstLineIndent(24);
        paragraph.setMultipliedLeading(1.2f).setMarginTop(18).setMarginBottom(23);
        cell.add(paragraph);
        table.addCell(cell);

        table.addCell(createTableCellNoBorderLeft("车辆类型："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getVehicleType()));
        table.addCell(createTableCellNoBorderLeft("号牌号码："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getVehicleNumber()));
        table.addCell(createTableCellNoBorderLeft("机动车品牌："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getVehicleBrand()));
        table.addCell(createTableCellNoBorderLeft("机动车型号："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getVehicleModel()));
        table.addCell(createTableCellNoBorderLeft("发动机号码："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getEngineNumber()));
        table.addCell(createTableCellNoBorderLeft("车辆识别代号/车架号："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getVin()));

        table.addCell(createTableCellNoBorder().setHeight(10));
        table.addCell(createTableCellNoBorder().setHeight(10));
        table.addCell(createTableCellNoBorderLeft("机动车所有人："));
        table.addCell(createTableCellNoBorderRight(orderRecord.getOwnerName()));
        table.addCell(createTableCellNoBorderLeft("注册登记日期："));
        table.addCell(createTableCellNoBorderRight(DateUtil.formatDate(orderRecord.getRegistrationDate(),
                DateUtil.DATE_FORMAT)));
        table.addCell(createTableCellNoBorderLeft("注销日期："));
        table.addCell(createTableCellNoBorderRight(DateUtil.formatDate(orderRecord.getCancellationDate(),
                DateUtil.DATE_FORMAT)));

        cell = createTableCellNoBorder(null, 1, 2, XINHUA_SONGTI, 14, 0, 10).setPaddingTop(0).setPaddingBottom(0);
        paragraph = new Paragraph(getTexts("我所已收回：", orderRecord.getRecoveredMaterials())).setFirstLineIndent(24);
        cell.add(paragraph);
        table.addCell(cell);
        table.addCell(createTableCellNoBorder().setHeight(10));
        table.addCell(createTableCellNoBorder().setHeight(10));
        cell = createTableCellNoBorder(null, 1, 2, XINHUA_SONGTI, 14, 0, 10).setPaddingTop(0).setPaddingBottom(0);
        paragraph = new Paragraph(getTexts("机动车所有人因故未能交回：", orderRecord.getUnrevokedMaterials()))
                .setFirstLineIndent(24);
        cell.add(paragraph);
        table.addCell(cell);
        table.addCell(createTableCellNoBorder().setHeight(72));
        table.addCell(createTableCellNoBorder().setHeight(72));

        table.addCell(createTableCellNoBorder(orderRecord.getVehicleManagementOffice(), 1, 2, XINHUA_SONGTI, 14, 0, 10)
                .setPaddingTop(0).setPaddingBottom(0).setPaddingLeft(tableWidth / 2)
                .setTextAlignment(TextAlignment.CENTER));
        table.addCell(createTableCellNoBorder("（盖章）", 1, 2, XINHUA_SONGTI, 14, 0, 0)
                .setPaddingTop(18).setPaddingBottom(2).setPaddingLeft(tableWidth / 2)
                .setTextAlignment(TextAlignment.CENTER));
        table.addCell(createTableCellNoBorder(DateUtil.formatDate(orderRecord.getCancellationDate(),
                DateUtil.CHINESE_DATE_FORMAT), 1, 2, XINHUA_SONGTI, 14, 0, 0)
                .setPaddingTop(0).setPaddingBottom(82).setPaddingLeft(tableWidth / 2)
                .setTextAlignment(TextAlignment.CENTER));

        document.add(table);
    }

    public static void createCancellationCertificate2(Document document, OrderRecord orderRecord) throws IOException {
        document.setMargins(68, 60, 68, 60);
        document.add(new Paragraph("机动车注销证明书").setFont(createFont(XINHUA_SONGTI)).setFontSize(21)
                .setTextAlignment(TextAlignment.CENTER).setFirstLineIndent(-40).setMarginBottom(35));

        int pageCount = document.getPdfDocument().getNumberOfPages();
        Rectangle rectangle = document.getPdfDocument().getPage(pageCount).getPageSize();
        float tableWidth = rectangle.getWidth() - 120;
        UnitValue[] unitValues = new UnitValue[] {
                UnitValue.createPercentValue(37),
                UnitValue.createPercentValue(63)
        };
        Table table = new Table(unitValues);
        table.setWidth(tableWidth);
        table.setBorder(new SolidBorder(new DeviceRgb(0, 0, 0), 1));

        Cell cell = createTableCellNoBorder(null, 1, 2, FANGZHENG_FANGSONG_GBK, 16, 0, 0).setPaddings(0, 12, 0, 12);
        Paragraph paragraph = new Paragraph().setFirstLineIndent(32).setMultipliedLeading(1.2f).setMarginTop(25);
        paragraph.add(new Text("在我所登记的下列机动车，因  "));
        paragraph.add(new Text("报废\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0")
                .setUnderline(0.75f, -5));
        paragraph.add(new Text("已办理注销登记。"));
        cell.add(paragraph);
        table.addCell(cell);

        table.addCell(createTableCellNoBorderLeft2("车辆类型："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getVehicleType()));
        table.addCell(createTableCellNoBorderLeft2("号牌号码："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getVehicleNumber()));
        table.addCell(createTableCellNoBorderLeft2("机动车品牌："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getVehicleBrand()));
        table.addCell(createTableCellNoBorderLeft2("机动车型号："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getVehicleModel()));
        table.addCell(createTableCellNoBorderLeft2("发动机号码："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getEngineNumber()));
        table.addCell(createTableCellNoBorderLeft2("车辆识别代号/车架号："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getVin()));
        table.addCell(createTableCellNoBorderLeft2("机动车所有人："));
        table.addCell(createTableCellNoBorderRight2(orderRecord.getOwnerName()));
        table.addCell(createTableCellNoBorderLeft2("注册登记日期："));
        table.addCell(createTableCellNoBorderRight2(DateUtil.formatDate(orderRecord.getRegistrationDate(),
                DateUtil.DATE_FORMAT)));
        table.addCell(createTableCellNoBorderLeft2("注销日期："));
        table.addCell(createTableCellNoBorderRight2(DateUtil.formatDate(orderRecord.getCancellationDate(),
                DateUtil.DATE_FORMAT)));

        cell = createTableCellNoBorder(null, 1, 2, FANGZHENG_FANGSONG_GBK, 16, 0, 0).setPaddings(0, 22, 0, 12);
        paragraph = new Paragraph(getTexts("我所已收回：", orderRecord.getRecoveredMaterials()))
                .setFirstLineIndent(32).setMultipliedLeading(1.2f);
        cell.add(paragraph);
        table.addCell(cell);
        table.addCell(createTableCellNoBorder2().setHeight(72));
        table.addCell(createTableCellNoBorder2().setHeight(72));

        table.addCell(createTableCellNoBorder(orderRecord.getCompanyName(), 1, 2,
                FANGZHENG_FANGSONG_GBK, 16, 0, 32).setPaddingTop(0).setPaddingBottom(0));
        table.addCell(createTableCellNoBorder("（盖章）", 1, 2, FANGZHENG_FANGSONG_GBK, 16, 0, 0)
                .setPaddingTop(0).setPaddingBottom(0).setPaddingLeft(tableWidth / 2)
                .setTextAlignment(TextAlignment.CENTER));
        table.addCell(createTableCellNoBorder(DateUtil.formatDate(orderRecord.getCancellationDate(),
                DateUtil.CHINESE_DATE_FORMAT), 1, 2, FANGZHENG_FANGSONG_GBK, 16, 0, 0)
                .setPaddingTop(0).setPaddingBottom(22).setPaddingLeft(tableWidth / 2)
                .setTextAlignment(TextAlignment.CENTER));

        document.add(table);
    }

    private static PdfFont createFont(String fontName) throws IOException {
        return PdfFontFactory.createRegisteredFont(FONT_MAP.get(fontName), PdfEncodings.IDENTITY_H,
                PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
    }

    private static PdfFont createFont(String fontName, int style) throws IOException {
        return PdfFontFactory.createRegisteredFont(FONT_MAP.get(fontName), PdfEncodings.IDENTITY_H,
                PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, style);
    }

    private static Cell createTableCell(String text, int rowspan, int colspan, String fontName) throws IOException {
        Cell cell = new Cell(rowspan, colspan);
        cell.setTextAlignment(TextAlignment.CENTER);
        cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
        cell.setFont(createFont(fontName)).setFontSize(10.5f);
        if (text != null) {
            cell.add(new Paragraph(text).setMultipliedLeading(1));
        }
        return cell;
    }

    private static Cell createTableCell(String text, int rowspan, int colspan, String fontName,
                                        float height) throws IOException {
        height = height <= 0 ? 36.6f : height;
        return createTableCell(text, rowspan, colspan, fontName).setHeight(height).setPadding(2.5f);
    }

    private static Cell createTableCell(String text, int rowspan, int colspan, String fontName,
                                        float height, float padding) throws IOException {
        return createTableCell(text, rowspan, colspan, fontName, height).setPadding(padding);
    }

    private static Cell createTableCellNoBorder(String text, int rowspan, int colspan, String fontName,
                                                float height, float padding) throws IOException {
        return createTableCellNoBorder(text, rowspan, colspan, fontName, 10.2f, height, padding);
    }

    private static Cell createTableCellNoBorder(String text, int rowspan, int colspan, String fontName, float fontSize,
                                                float height, float padding) throws IOException {
        return createTableCellNoBorder(text, rowspan, colspan, fontName, fontSize, height, padding, 0);
    }

    private static Cell createTableCellNoBorder(String text, int rowspan, int colspan, String fontName, float fontSize,
                                                float height, float padding, float leading) throws IOException {
        Cell cell = new Cell(rowspan, colspan).setVerticalAlignment(VerticalAlignment.MIDDLE);
        cell.setFont(createFont(fontName)).setFontSize(fontSize);
        if (text != null) {
            if (leading > 0) {
                text = String.join("\n", text.split(""));
            }
            Paragraph paragraph = new Paragraph(text);
            if (leading > 0) {
                paragraph.setFixedLeading(leading);
            }
            cell.add(paragraph);
        }
        cell.setBorder(Border.NO_BORDER).setPadding(padding);
        if (height > 0) {
            cell.setHeight(height);
        }
        return cell;
    }

    private static Cell createTableCellNoBorder() throws IOException {
        Cell cell = new Cell(1, 1).setVerticalAlignment(VerticalAlignment.MIDDLE).setHeight(20);
        cell.setFont(createFont(XINHUA_SONGTI)).setFontSize(14);
        cell.setBorder(Border.NO_BORDER).setPaddings(0, 0, 0, 0);
        return cell;
    }

    private static Cell createTableCellNoBorderLeft(String text) throws IOException {
        Cell cell = createTableCellNoBorder().setTextAlignment(TextAlignment.RIGHT);
        cell.add(new Paragraph(text).setMultipliedLeading(1));
        return cell;
    }

    private static Cell createTableCellNoBorderRight(String text) throws IOException {
        Cell cell = createTableCellNoBorder();
        cell.add(new Paragraph(text).setMultipliedLeading(1));
        return cell;
    }

    private static Cell createTableCellNoBorder2() throws IOException {
        Cell cell = new Cell(1, 1).setVerticalAlignment(VerticalAlignment.MIDDLE);
        cell.setFont(createFont(FANGZHENG_FANGSONG_GBK)).setFontSize(16);
        cell.setBorder(Border.NO_BORDER).setPadding(0);
        return cell;
    }

    private static Cell createTableCellNoBorderLeft2(String text) throws IOException {
        Cell cell = createTableCellNoBorder2().setTextAlignment(TextAlignment.RIGHT);
        cell.add(new Paragraph(text).setMultipliedLeading(1.2f));
        return cell;
    }

    private static Cell createTableCellNoBorderRight2(String text) throws IOException {
        Cell cell = createTableCellNoBorder2();
        cell.add(new Paragraph(text).setMultipliedLeading(1.2f));
        return cell;
    }

    private static Cell addImageToCell(Cell cell, String imagePath, float left, float bottom, float width)
            throws MalformedURLException {
        Image image = new Image(ImageDataFactory.create(imagePath)).setAutoScale(false)
                .setFixedPosition(left, bottom, width);
        return cell.add(image);
    }

    private static Cell addImageToCell(Cell cell, Image image, float left, float bottom, float width) {
        if (image != null) {
            image.setAutoScale(false).setFixedPosition(left, bottom, width);
            cell.add(image);
        }
        return cell;
    }

    private static String getTexts(String... texts) {
        String result = "";
        if (texts != null) {
            for (String text : texts) {
                result = result.concat(text == null ? "" : text);
            }
        }
        return result;
    }


    static class BackgroundEventHandler implements IEventHandler {

        private List<DeviceRgb> backgroundColors;

        private List<String> backgroundImages;

        private int index = 0;

        public BackgroundEventHandler(List<DeviceRgb> backgroundColors, List<String> backgroundImages) {
            this.backgroundColors = backgroundColors;
            this.backgroundImages = backgroundImages;
        }

        @Override
        public void handleEvent(Event event) {
            if (backgroundImages != null && backgroundImages.size() > 0) {
                setBackgroundImage(event, backgroundImages.get(index % backgroundImages.size()));
            } else if (backgroundColors != null && backgroundColors.size() > 0) {
                setBackgroundColor(event, backgroundColors.get(index % backgroundColors.size()));
            }
            index = index + 1;
        }

        private void setBackgroundColor(Event event, DeviceRgb backgroundColor) {
            PdfDocumentEvent pdfDocumentEvent = (PdfDocumentEvent) event;
            PdfDocument pdfDocument = pdfDocumentEvent.getDocument();
            PdfPage pdfPage = pdfDocumentEvent.getPage();
            Rectangle rectangle = pdfPage.getPageSize();
            PdfCanvas pdfCanvas = new PdfCanvas(pdfPage.newContentStreamBefore(), pdfPage.getResources(), pdfDocument);
            pdfCanvas.saveState().setFillColor(backgroundColor).rectangle(rectangle).fill().restoreState();
        }

        private void setBackgroundImage(Event event, String backgroundImage) {
            PdfDocumentEvent pdfDocumentEvent = (PdfDocumentEvent) event;
            PdfDocument pdfDocument = pdfDocumentEvent.getDocument();
            PdfPage pdfPage = pdfDocumentEvent.getPage();
            Rectangle rectangle = pdfPage.getPageSize();
            PdfCanvas pdfCanvas = new PdfCanvas(pdfPage.newContentStreamBefore(), pdfPage.getResources(), pdfDocument);
            try {
                ImageData imageData = ImageDataFactory.create(backgroundImage);
                pdfCanvas.addImageFittedIntoRectangle(imageData, rectangle, false);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

    }

}
